﻿using System;
using JetBrains.Annotations;
using UnityEngine;

public static class UnityComponentExt
{
	private static Type DefaultTypeRouter<T>(T self, Type type)
	{
		return type;
	}

	private static void DefaultInitAction<T>(T component)
	{

	}


	/// <summary>
	/// 取得当前对象的某个组件 如果不存在 就添加!
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="self"></param>
	/// <param name="defaultInitAction"></param>
	/// <returns></returns>
	public static T GetComponentOrAdd<T>(this Component self) where T : Component
	{
		return self.GetComponentOrAdd<T>(DefaultInitAction);
	}

	public static T GetComponentOrAdd<T>(this Component self, [NotNull] Action<T> initAction) where T : Component
	{
		return self.GetComponentOrAdd<Component,T>(DefaultTypeRouter, DefaultInitAction);
	}

	/// <summary>
	/// 
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <typeparam name="T0"></typeparam>
	/// <param name="self"></param>
	/// <param name="typeRoute">return type must base on T</param>
	/// <param name="initAction"></param>
	/// <returns></returns>
	public static T GetComponentOrAdd<T0, T>(this T0 self, [NotNull] Func<T0, Type, Type> typeRoute, [NotNull] Action<T> initAction) where T : Component where T0 : Component
	{
		if (initAction == null) throw new ArgumentNullException(nameof(initAction));

		if (self == null) return null;
		var t = self.GetComponent<T>();
		if (t == null)
		{
			var srcType = typeof(T);
			var type = typeRoute(self, srcType);
			var rawComp = self.gameObject.AddComponent(type);
			t = rawComp as T;
			if (t.IsNullU())
			{
				Debug.LogFormat("{0} not convert to {1}", type.Name, srcType.Name);
				return null;
			}
			initAction(t);
		}
		return t;
	}
}
